package com.tengfei.main.course.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tengfei.common.core.domain.PageQuery;
import com.tengfei.common.core.page.TableDataInfo;
import com.tengfei.common.exception.ServiceException;
import com.tengfei.common.utils.DateUtils;
import com.tengfei.common.utils.StringUtils;
import com.tengfei.main.course.config.AliyunConfig;
import com.tengfei.main.course.domain.Res;
import com.tengfei.main.course.domain.bo.ResBo;
import com.tengfei.main.course.domain.vo.ResVo;
import com.tengfei.main.course.mapper.ResMapper;
import com.tengfei.main.course.service.IResService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import static com.tengfei.common.utils.file.MimeTypeUtils.RESOURCE_TYPE;

/**
 * 资源Service业务层处理
 *
 * @author tengfei
 * @date 2022-07-26
 */
@Slf4j
@Service
public class ResServiceImpl implements IResService {

    @Resource
    private ResMapper baseMapper;
    @Resource
    private AliyunConfig aliyunConfig;
    @Resource
    private OssServiceImpl ossService;

    /**
     * 查询资源
     */
    @Override
    public ResVo queryById(Long resId) {
        return baseMapper.selectVoById(resId);
    }

    /**
     * 查询资源列表
     */
    @Override
    public TableDataInfo<ResVo> queryPageList(ResBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Res> lqw = buildQueryWrapper(bo);
        Page<ResVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    private LambdaQueryWrapper<Res> buildQueryWrapper(ResBo bo) {
        LambdaQueryWrapper<Res> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getResName()), Res::getResName, bo.getResName());
        lqw.eq(bo.getResType() != null, Res::getResType, bo.getResType());
        lqw.orderByDesc(Res::getUpdateTime);
        return lqw;
    }

    /**
     * 修改资源
     */
    @Override
    public Boolean updateByBo(ResBo bo) {
        if (ObjectUtil.isNull(bo.getResId())) {
            throw new ServiceException("资源id为空");
        }
        Res update = BeanUtil.toBean(bo, Res.class);
        return baseMapper.updateById(update) > 0;
    }


    /**
     * 批量删除资源
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids) {
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    /*
     * 资源上传
     */
    @Override
    public ResVo uploadRes(MultipartFile file) {
        if (ObjectUtil.isNull(file)) {
            throw new ServiceException("上传文件为空");
        }
        long size = file.getSize();
        if (size / 1024 / 1024 > 20) {
            throw new ServiceException("上传文件大于20M");
        }

        Res res = new Res();
        // 判断文件类型
        /**
         * 1：图片
         * 2：音频
         * 3：文档（pdf/word）
         * 4：压缩文件
         * 5：其它
         */
        int fileType = 5;
        String extName = FileNameUtil.extName(file.getOriginalFilename());
        boolean flag = false;
        for (int i = 0; i < RESOURCE_TYPE.length; i++) {
            String[] TYPES = RESOURCE_TYPE[i];
            for (String TYPE : TYPES) {
                if (extName.equalsIgnoreCase(TYPE)) {
                    fileType = i + 1;
                    flag = true;
                    break;
                }
            }
            if (flag) {
                break;
            }
        }
        res.setResType(fileType);
        InputStream is = null;
        try {
            is = file.getInputStream();
        } catch (IOException e) {
            throw new ServiceException("上传文件失败");
        }
        // 构造路径
        String fileName = UUID.randomUUID().toString();
        String filePath = new StringBuilder(aliyunConfig.getRootPath())
                .append("/resources/")
                .append(DateUtils.datePath())
                .append("/")
                .append(fileName)
                .append(".")
                .append(extName)
                .toString();
        // 上传文件
        if (fileType == 1) {
            // 图片同步上传
            ossService.uploadImg(filePath, is);
        } else {
            // 其它文件异步上传
            ossService.uploadRes(filePath, is);
        }

        // 持久化到数据库
        res.setResUrl(aliyunConfig.getUrlPrefix() + filePath);
        res.setResSize(size);
        res.setCreateTime(new Date());
        res.setUpdateTime(new Date());
        res.setResName(FileNameUtil.mainName(file.getOriginalFilename()));
        boolean insert = baseMapper.insert(res) > 0;
        if (!insert) {
            throw new ServiceException("上传文件失败");
        }
        ResVo resVo = new ResVo();
        resVo.setResId(res.getResId());
        resVo.setResUrl(res.getResUrl());
        return resVo;
    }

    /**
     * 查询附件资源列表详细信息
     */
    @Override
    public List<ResVo> resListByIds(List<Long> resIds) {
        return baseMapper.selectVoList(new LambdaQueryWrapper<Res>()
                .in(Res::getResId, resIds));
    }
}
